<template>
    <el-tree-v2
        ref="treeRef"
        :data="treeData" 
        :props="props"
        highlight-current 
        :item-size="28"
        v-if="showTree"
        @node-click="nodeClicked"
        @node-contextmenu.prevent = "openContextMenu"
        :height="treeHeight">
        <template #default="{ node, data}">
            <el-icon color="purple" v-if="data.nodeType === 1" :size="20">
                <Folder />
            </el-icon>
            <el-icon color="purple"  v-else :size="20">
                <Document />
            </el-icon> 
            <span class="tree_item_lable">{{ node.label }}</span>
        </template>
    </el-tree-v2>

    <ContextMenu :menu-items="menuItems" ref="contextMenuRef" />

    <el-dialog v-model="dialogShow" :title="dialogTitle" width="400">
        <el-input v-model.trim="newFolderName" 
            placeholder="请输入新建文件夹的名称"
            maxlength="20"
            show-word-limit
            v-if="operationType === 1"/>
        <span v-else>确定删除?</span>
        <template #footer>
            <el-button @click="clickDialogCancel">取消</el-button>
            <el-button type="primary" @click="clickDialogConfirm">确定</el-button>
        </template>
    </el-dialog>

</template>

<script setup lang='ts' name='SpaceManager'>
    import { ref, onMounted, onUnmounted, reactive, watch } from "vue";
    import { Folder, Document } from '@element-plus/icons-vue';
    import { TreeNode, TreeNodeData } from "element-plus/es/components/tree-v2/src/types";
    import request from "@/requests/request";
    import ContextMenu from "@/components/ContextMenu.vue";
    import { ContextMenuItem } from "@/components/ContextMenu.vue";
    import { useTopBreadcrumbInfoStore } from "@/store/topBreadcrumbInfo";
    import { useWindowSize } from '@vueuse/core';
    import { UploadRawFile, UploadRequestOptions } from "@/types/type";
    import { useUserInfoStore } from "@/store/userInfo";


    const topBreadcrumbInfo = useTopBreadcrumbInfoStore()
    const userInfo = useUserInfoStore()
    const windowSize = useWindowSize()

    const contextMenuRef = ref<InstanceType<typeof ContextMenu>>();
    const menuItems = ref<ContextMenuItem[]>([]);

    let contextNode: TreeNode // 当前右键选中的节点
    let operationType: number  // 针对节点的操作类型, 1: 新建文件夹; 2: 删除文件夹；3：删除文件

    function openContextMenu(event: MouseEvent, nodeData: TreeNodeData, node: TreeNode) {
        menuItems.value.splice(0, menuItems.value.length)
        switch (nodeData.nodeType) {
            case 1: {  // 文件夹
                menuItems.value.splice(0, menuItems.value.length)
                menuItems.value.push({
                    actionType: 1,
                    name: "新建文件夹",
                    action: (node: TreeNode) => {
                        contextNode = node
                        newFolderName.value = ""
                        dialogShow.value = true
                        operationType = 1
                    },
                })
                menuItems.value.push({
                    actionType: 1,
                    name: "删除文件夹",
                    action: (node: TreeNode) => {
                        contextNode = node
                        newFolderName.value = ""
                        dialogShow.value = true
                        operationType = 2
                    },
                })
                menuItems.value.push({
                    actionType: 2,
                    name: "上传文件",
                    beforeUpload :(uploadFile: UploadRawFile) => {
                        console.log("beforeUpload()", uploadFile)
                    },
                    upload: (uploadOptions: UploadRequestOptions) => {
                        uploadFile(uploadOptions.file, nodeData as NodeData)
                    }
                })
            }
                break;
            case 2: { // 文件
                menuItems.value.push({
                    actionType: 1,
                    name: "删除文件",
                    action: (node: TreeNode) => {
                        contextNode = node
                        newFolderName.value = ""
                        dialogShow.value = true
                        operationType = 3
                    },
                })
            }
                break;
            default:
                break;
        }
        contextMenuRef.value?.openMenu(event, node)
    }

    const treeRef = ref()
    interface NodeData {
        id: string  // 节点程径
        label: string  // 节点名称
        children?: NodeData[]  // 子节点
        nodeType: number  // 节点类型 1:目录；2:文件；
    }

    const props = {
        value: 'id',
        label: 'label',
        children: 'children',
    }

    let showTree = ref(false)
    const treeData = reactive<Array<NodeData>>([])

    const dialogShow = ref(false)
    const dialogTitle = ref("")
    const newFolderName = ref("")

    function clickDialogCancel() {
        dialogShow.value = false
    }

    function clickDialogConfirm() {
        console.log(contextNode.data)
        switch (operationType) {
            case 1: {
                newFolder(contextNode)
            }
                break
            case 2: {
                deleteFolder(contextNode)
            }
                break
            case 3: {
                deleteFile(contextNode)
            }
                break
        }
        dialogShow.value = false
    }

    const treeHeight = ref(0)

    function setTreeHeight(showTopBreadcrumb: boolean) {
        if (showTopBreadcrumb) {
            treeHeight.value = windowSize.height.value - 100  // TODO hard code
        } else {
            treeHeight.value = windowSize.height.value - 60
        }
    }

    function handleWindowResize() {
        setTreeHeight(topBreadcrumbInfo.showTopBreadcrumb)
    }

    onMounted(()=> {
        setTreeHeight(topBreadcrumbInfo.showTopBreadcrumb)
        requestTreeData()
        window.addEventListener('resize', handleWindowResize);
    })

    onUnmounted(()=>{
        window.removeEventListener('resize', handleWindowResize);
    })

    watch(()=>topBreadcrumbInfo.showTopBreadcrumb, (newVal)=> {
        setTreeHeight(newVal)
    })

    function requestTreeData() {
        request.post("/listAllFilePath").then((res: any)=> {
            const {data, resCode, message} = res.data
            console.log("/listAllFilePath", data, resCode, message);
            if (data && data.length > 0) {
                showTree.value = true
                // 索引签名
                const nodeMap: { [key: string]: NodeData } = {};
                for (let fileCount = 0; fileCount < data.length; fileCount++) {
                    const itemList = data[fileCount].split('/')
                    console.log(data[fileCount], itemList);
                    let id = ''
                    for(let itemCount = 0; itemCount < itemList.length; itemCount++) {
                        const itemName = itemList[itemCount]
                        if (id.length > 0) {
                            id = `${id}/${itemName}`
                        } else {
                            id = itemName 
                        }
                        let nodeData: NodeData
                        if (id in nodeMap) {
                            nodeData = nodeMap[id]
                            
                        } else {
                            nodeData = {id, "label": itemName, children: undefined, nodeType: 2}  
                            treeData.push(nodeData)
                        }
                        nodeMap[id] = nodeData

                        // 为非叶子节点添加子节点
                        if (itemCount < itemList.length - 1) {
                            if (nodeData.children === undefined) {
                                nodeData.children = new Array<NodeData>()
                            }
                            const childCount = itemCount + 1
                            const childItemName = itemList[childCount]
                            const childId = `${id}/${childItemName}`
                            let childNodeData: NodeData
                            if (childId in nodeMap) {
                                childNodeData = nodeMap[childId]
                            } else {
                                childNodeData = {id: childId, "label": childItemName, children: undefined, nodeType: 2}
                                nodeData.nodeType = 1
                                if (childItemName !== ".G_STORE") {
                                    nodeData.children.push(childNodeData)
                                }
                            }
                            nodeMap[childId] = childNodeData
                        }
                    }
                }
                console.log("/listAllFilePath", treeData);
            }
        }).catch((reason: any)=> {
            console.log("/listAllFilePath", reason); 
        })
    }

    function nodeClicked(data: TreeNodeData, node: TreeNode, e: MouseEvent) {
        contextMenuRef.value!.closeMenu()
        console.log(data, node, e);
    }

    // 新建文件夹
    function newFolder(node: TreeNode) {
        const nodeData = node.data
        const folderPath = nodeData.id + "/" + newFolderName.value
        const formData = new FormData()
        formData.append("folderPath", folderPath)
        const headers = {
            ContentType: "application/x-www-form-urlencoded",
        }
        request.post("/newFolder", formData, {headers}).then((res: any)=> {
            console.log("/newFolder", res);
            const {data} = res.data
            if (data) {
                const newNodeData: NodeData = {id: folderPath, "label": newFolderName.value, children: undefined, nodeType: 1} 
                if (nodeData.children) {
                    nodeData.children.push(newNodeData)
                } else {
                    nodeData.children = new Array<NodeData>()
                    nodeData.children.push(newNodeData)
                }
                treeRef.value.setData(treeData)  // TODO 为什么需要重尊新设置一下数据才能更新UI
            }
        }).catch((reason: any)=> {
            console.log(reason);
        }) 
    }

    // 删除文件夹
    function deleteFolder(node: TreeNode) {
        const nodeData = node.data 
        const folderPath = nodeData.id
        const formData = new FormData()
        formData.append("folderPath", folderPath)
        const headers = {
            ContentType: "application/x-www-form-urlencoded",
        }
        request.post("/deleteFolder", formData, {headers}).then((res: any)=> {
            console.log("/deleteFolder", res);
            const {data} = res.data
            if (data) {
                const parentNode = node.parent
                const index = parentNode?.data.children?.indexOf(nodeData)
                console.log("/deleteFolder, index=", index);
                if (index > -1) {
                    parentNode?.data.children?.splice(index, 1)
                }
                treeRef.value.setData(treeData)  // TODO 为什么需要重新设置一下数据才能更新UI
            }
        }).catch((reason: any)=> {
            console.log(reason);
        }) 
    }

    
    // 删除文件
    function deleteFile(node: TreeNode) {
        const nodeData = node.data
        console.log(nodeData)
        const filePath = nodeData.id
        const formData = new FormData()
        formData.append("filePath", filePath)
        const headers = {
            ContentType: "application/x-www-form-urlencoded",
        }
        request.post("/deleteFile", formData, {headers}).then((res: any)=> {
            console.log("/deleteFile", res);
            const {data} = res.data
            if (data) {
                const parentNode = node.parent
                const index = parentNode?.data.children?.indexOf(nodeData)
                console.log("/deleteFile, index=", index);
                if (index > -1) {
                    parentNode?.data.children?.splice(index, 1)
                }
                treeRef.value.setData(treeData)
            }
        }).catch((reason: any)=> {
            console.log(reason);
        }) 
    }

    function uploadFile(file: File, nodeData: NodeData) {
        console.log("uploadFile()", file, nodeData)
        const headers = {
            ContentType: "multipart/form-data",
        }
        const formData = new FormData();
        formData.append("file", file);
        formData.append("token", userInfo.token)
        formData.append("folderPath", (nodeData as NodeData).id)
        request.post('/upload', formData, { headers }).then(res => {
            console.log(res.data);
            const { data, message, resCode } = res.data
            console.log(data, message, resCode)
            if (resCode === 0) {
                const folderPath = (nodeData as NodeData).id
                const fileName = file.name
                const filePath = folderPath + "/" + fileName
                const fileNodeData: NodeData = {id: filePath, "label": fileName, children: undefined, nodeType: 2};
                nodeData.children?.push(fileNodeData)
                treeRef.value.setData(treeData)  // TODO 为什么需要重新设置一下数据才能更新UI
            }
        }).catch(error => {
            console.error(error);
        });
    }

</script>

<style scoped lang='scss'>
    .tree_item_lable {
            font-size: 16px;
            margin-left: 10px;
        }
    .new_folder_container {
        display: flex;
    }
</style>